package lk.icta.user.dao.impl;

import lk.icta.common.AppConstants;
import lk.icta.common.dao.impl.BaseDAO;
import lk.icta.common.entity.DSDivision;
import lk.icta.user.dao.UserDAO;
import lk.icta.user.entity.User;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.Query;
import java.util.List;

/**
 * @author Mahesha Kalpanie
 */
public class UserDAOImpl extends BaseDAO implements UserDAO {

    @Transactional(propagation = Propagation.MANDATORY)
    public void addUser(User user) {
        em.persist(user);
    }

    @Transactional(propagation = Propagation.MANDATORY)
    public void updateUser(User user) {
        em.merge(user);
    }

    @Transactional(propagation = Propagation.NEVER, readOnly = true)
    public List<User> getAllUsers() {
        Query q = em.createNamedQuery("getAllUser");
        return q.getResultList();
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public User getUserByUserName(String userName) {
        logger.debug("Find user by userName: {}", userName);
        Query q = em.createNamedQuery("getUserByUserName");
        q.setParameter("username", userName);
        List result = q.getResultList();
        if (!result.isEmpty()) {
            return (User) result.get(0);
        } else {
            return null;
        }
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public User getUserByEmail(String email) {
        logger.debug("Find user by Email: {}", email);
        Query q = em.createNamedQuery("getUserByEmail");
        q.setParameter("email", email);
        List result = q.getResultList();
        if (!result.isEmpty()) {
            return (User) result.get(0);
        } else {
            return null;
        }
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public List<User> getUsersByOrganization(int organizationId, User user) {
        Query q = em.createNamedQuery("getUsersByOrganization");
        q.setParameter("organizationId", organizationId);
        List result = q.getResultList();
        return result;

    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public List<User> getORPIIUsersByOrganization(int organizationId, User user) {
        Query q = em.createNamedQuery("getORPIIUsersByOrganization");
        q.setParameter("organizationId", organizationId);
        q.setParameter("roleId", AppConstants.ORPII_USER_ROLE);
        List result = q.getResultList();
        return result;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public List<User> getNewURMGOIUsersByOrganization(int organizationId, User user) {
        Query q = em.createNamedQuery("getNewURMGOIUsersByOrganization");
        q.setParameter("organizationId", organizationId);
        q.setParameter("roleId", AppConstants.URMGOI_USER_ROLE);
        q.setParameter("state", User.State.INACTIVE);
        List result = q.getResultList();
        return result;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public List<User> getUsersByRole(String role) {
        Query q = em.createNamedQuery("getUsersByRole");
        q.setParameter("roleId", role);
        q.setParameter("state", User.State.ACTIVE);
        List result = q.getResultList();
        return result;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public List<User> getUsersByRoleDS(String role, int dsId, User user) {
        Query q = em.createNamedQuery("getUsersByRoleDS");
        q.setParameter("roleId", role);
        q.setParameter("dsId", dsId);
        q.setParameter("state", User.State.ACTIVE);
        List result = q.getResultList();
        return result;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public List<User> getUsersByRoleProvince(String role, int provinceId, User user) {
        Query q = em.createNamedQuery("getUsersByRoleProvince");
        q.setParameter("roleId", role);
        q.setParameter("provinceId", provinceId);
        q.setParameter("state", User.State.ACTIVE);
        List result = q.getResultList();
        logger.debug("searchUsersByRole SIZE :{}", result.size());
        return result;
    }

    @Transactional(propagation = Propagation.SUPPORTS)
    public List<User> getAllUsersByPA(int dsId, User user) {
        Query q = em.createNamedQuery("getAllUsersByPA");
        q.setParameter("provinceId", dsId);
        q.setParameter("state", User.State.ACTIVE);
        List result = q.getResultList();
        return result;
    }
}

